﻿function mKook(options) {
    //Иницализация
    this.isOnline = true;
    this.dbID = options.dbName;
    this.dbVersion = options.dbVersion;
    this.dbDesc = options.dbDesc;
    this.dbSize = options.dbSize;
    this.dbTables = options.dbTables;
    //Текущая база данных
    this.db = null;
    //Текущая модель представления
    this.viewModel = options.viewModel;
    //Запускаем приложение
    this.run = function () {
        //Загружаем БД
        this.dbInit();
        //Knockout

    }
    //Инициализация приложения
    this.dbInit = function () {
        //Открываем базу данных
        this.dbOpen(this.dbID, this.dbVersion, this.dbDesc, this.dbSize);
        //Удалить таблицу запросов
        this.dbDropTable('tbl_request');
        //Создаем или открываем таблицу запросов, моделей и шаблонов. Формируем json объект в качестве аргумента
        this.dbCreateTables(this.dbTables);
        //Инициализируем Knockout
        this.koInit();
    }
    //Инициализация Knockout
    this.koInit = function () {
        ko.applyBindings(this.viewModel);
    }
    // Установка viewModel
    this.setViewModel = function (vm) {
        this.viewModel = vm;
    }

    this.getKey = function () {
        var key = new Object();
        if (this.viewModel.key.length > 0) {
            for (var i = 0; i < this.viewModel.key.length; i++) {
                var name = this.viewModel.key[i];
                var value = this.viewModel.data[name]();
                key[name] = value;
            }
        }
        strKey = JSON.stringify(key);
        return strKey;
    }
    //Создать запрос
    this.doRequest = function (req) {
        //Сформировать данные для запроска
        //Время запроса
        var time = Date().toString();
        //Статус запроса (первый статус всегда 'wait')
        var stat = 'wait';
        //Проверка запроса
        if (this.isRequestOk) {
            //Найти запрос в базе
            //Если запрос найден, то загрузить
            if (this.findRequest(req)) {
                this.getRequest(req);
            }
            else {
                this.setRequest(req);
            }

        }
    }
    //Найти запрос
    this.findRequest = function (req) {
        var query = 'SELECT * FROM tbl_request WHERE name = ' + req.name + ' AND key = ' + req.key;
        var rows = null;
        this.dbExecuteQuery(query, '', function (result) { rows = result.rows; });
        if (rows == null || rows.lenght <= 0) { return false; }
        if (rows != null && rows.length > 1) { return false; }
        if (rows != null && rows[0] != null && rows[0].toString() != '') { return rows[0]; };
    }
    //Добавить запрос в таблицу
    this.setRequest = function (req) {
        var strValues = '';
        var query = 'INSERT INTO tbl_request (time, stat, name, key, data) VALUES(' + strValues + ')';
        //                { 'name': 'time', 'value': req.time },
        //                { 'name': 'stat', 'value': req.stat },
        //                { 'name': 'name', 'value': req.name },
        //                { 'name': 'key', 'value': req.key },
        //                { 'name': 'data', 'value': req.data }
        //            ]
        //            }
        //        ]
        //        };
        this.dbExecuteQuery(query);
    }
    //Взять запрос из таблицы
    this.getRequest = function (req) {
        query = 'SELECT * from tbl_request WHERE key=' + req.key;
        this.dbExecuteQuery(query, '', function (result) {
            for (var i = 0; i < result.rows.length; i++) {
                var row = result.rows[i];
                req.id = row.id;
                req.time = row.time;
                req.stat = row.stat;
                req.name = row.name;
                req.key = row.key;
                req.data = row.data;
            }
        });
    }
    //Загрузить модель представления
    this.loadViewModel = function (viewModel) {
    }
    //Проверка правильности запроса
    this.isRequestOk = function () {
        return true;
    }
    //Открытие базы
    this.dbOpen = function (name, version, desc, size) {	// Open database         
        if (window.openDatabase) {
            this.db = openDatabase(name, version, desc, size);
            if (!this.db) {
                debugTxt = ("Failed to open the database on disk.  This is probably because the version was bad or there is not enough space left in this domain's quota");
            }
        } else {
            debugTxt = ("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");
        }
    }
    //Cоздание таблицы
    this.dbCreateTables = function (tbJson) {
        var $this = this;
        for (x = 0; x < tbJson.createTables.length; x++) {	// Loop in the json for every table
            createQuery(tbJson.createTables[x]);
        }
        function createQuery(tbNode) {			// Create the SQL that will create the tables
            debugTxt = "create table " + tbNode.table;
            var stringQuery = "CREATE TABLE " + tbNode.table + " (";
            nodeSize = tbNode.property.length - 1;
            for (y = 0; y <= nodeSize; y++) {
                stringQuery += tbNode.property[y].name + " " + tbNode.property[y].type;
                if (y != nodeSize) { stringQuery += ", " }
            }
            stringQuery += ")";
            $this.dbExecuteQuery(stringQuery, debugTxt);
        }
    }
    //Выполнить запрос
    this.dbExecuteQuery = function (stringQuery, debugTxtRaw, fn) {
        $this = this;
        debugTxtRaw += "<br> SQL: " + stringQuery;
        callback = fn;
        //debugger;
        this.db.transaction(function (tx) {
            tx.executeSql(stringQuery, [], function (tx, result) { 	// Execute SQL
                if (callback) { callback(result); } 				// Execute callback
                if ($this.debugging) {
                    debugTxtRaw += "<br><span style='color:green'>success</span> ";
                    $this.debug(debugTxtRaw);
                }
            }, function (tx, error) {
                debugTxtRaw += "<br><span style='color:red'>" + error.message + "</span> ";
                if ($this.debugging) {
                    $this.debug(debugTxtRaw);
                }
            });
        });
    }
    //Удалить запись из таблицы
    this.dbDeleteRow = function (table, key, value) {		// Simple Delete row
        stringQuery = "DELETE FROM " + table + " WHERE " + key + " = " + value;
        debugTxt = "delete row" + key + " " + value;
        this.dbExecuteQuery(stringQuery, debugTxt);
    }
    //Выбрать всю таблицу
    this.dbSelectAll = function (table, fn) {
        stringQuery = "SELECT * FROM " + table;
        debugTxt = "selecting everything in table " + table;
        this.dbExecuteQuery(stringQuery, debugTxt, fn);
    }
    //Удалить таблицу
    this.dbDropTable = function (table) {
        stringQuery = "DROP TABLE " + table;
        debugTxt = "delete table " + table;
        this.dbExecuteQuery(stringQuery, debugTxt);
    }
    // Создание окна отладки
    this.debug = function (error) {
        if (!$("#debugMode")[0]) {
            $("body").append("<div style='position:abolute;top:0 !important;left:0 !important;width:100% !important;min-height:100px !important; height:300px; overflow:scroll;z-index:1000; display:block; opacity:0.8; background:#000;-webkit-backface-visibility:visible ' id='debugMode'></div>");
        }
        $("#debugMode").append("<div class='debugerror'>" + error + "</div>");
    }

    //////////////////////////////
    // Функции загрузки шаблона //
    //////////////////////////////
    this.loadModelTemplate = function (templates) {
        /// <summary>
        /// Загружает шаблон модели
        /// </summary>
        /// <param name="templates">Шаблоны</param>

        var headerString, contentString, footerString;

        switch (this.viewModel.name) {
            case 'modelAuth':
                headerString = templates.headers.authView;
                contentString = templates.contents.authView;
                footerString = templates.footers.authView;
                break;
            case 'modelList':
                headerString = templates.headers.objectListView;
                contentString = templates.contents.objectListView;
                footerString = templates.footers.objectListView;
                break;
            case 'modelInit':
            default:
                headerString = templates.headers.initView;
                contentString = templates.contents.initView;
                footerString = templates.footers.initView;
                break;
        }

        var $page = $("#mainPage");
        // Get the header for the page.
        var $header = $page.children(":jqmData(role=header)");
        // Get the content area element for the page.
        var $content = $page.children(":jqmData(role=content)");
        // Get the footer area element for the page.
        var $footer = $page.children(":jqmData(role=footer)");

        $header.html(headerString);
        $content.html(contentString);
        $footer.html(footerString);

        this.koInit();

        $page.trigger('create');
    }
}